package edu.gatech.mobile.scene.ui.camera;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.List;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.hardware.GeomagneticField;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.Contacts.Intents;
import android.util.Log;
import edu.gatech.mobile.scene.AppConstants;
import edu.gatech.mobile.scene.R;
import edu.gatech.mobile.scene.model.ImageInfo;
import edu.gatech.mobile.scene.provider.impl.ImageInfoDBImpl;
import edu.gatech.mobile.scene.ui.image.ActiveEvaluationActivity;
import edu.gatech.mobile.scene.ui.image.ImageViewActivity;

public final class CaptureActivityHandler extends Handler {

	
	public static final String IMG_FOLDER = "gatech";
	private static final String TAG = CaptureActivityHandler.class
			.getSimpleName();

	private final CaptureActivity activity;
	private State state;
	private final CameraManager cameraManager;
	private ImageInfoDBImpl imageDB;

	private enum State {
		PREVIEW, DONE
	}

	CaptureActivityHandler(CaptureActivity activity, CameraManager cameraManager) {
		this.activity = activity;
		imageDB = new ImageInfoDBImpl(activity.getApplicationContext());
		// Start ourselves capturing previews and decoding.
		this.cameraManager = cameraManager;
		cameraManager.startPreview();
		restartPreview();
	}

	@Override
	public void handleMessage(Message message) {
		switch (message.what) {
		case R.id.auto_focus:
			// Log.d(TAG, "Got auto-focus message");
			// When one auto focus pass finishes, start another. This is the
			// closest thing to
			// continuous AF. It does seem to hunt a bit, but I'm not sure what
			// else to do.
			if (state == State.PREVIEW) {
				cameraManager.requestAutoFocus(this, R.id.auto_focus);
			}
			break;
		case R.id.restart_preview:
			Log.d(TAG, "Got restart preview message");
			restartPreview();
			break;
		case R.id.preview:
			cameraManager.requestPreviewFrame(this, R.id.preview);
			activity.getViewfinderView().drawViewfinder();
			break;
		case R.id.capture:
			decode((byte[]) message.obj, message.arg1, message.arg2);
			cameraManager.requestPreviewFrame(this, R.id.preview);
		}
	}

	public void quitSynchronously() {
		state = State.DONE;
		cameraManager.stopPreview();
	}

	public void restartPreview() {
		state = State.PREVIEW;
		activity.drawViewfinder();
		cameraManager.requestPreviewFrame(this, R.id.preview);
		cameraManager.requestAutoFocus(this, R.id.auto_focus);
	}

	private void decode(byte[] data, int width, int height) {
		List<Point> horizonPoints = activity.getViewfinderView().getHorizonPoints();
		PlanarYUVLuminanceSource source = activity.getCameraManager()
				.buildLuminanceSource(data, width, height);
		Bitmap bitmap = source.renderColorBitmap();
		String sdcardDir = Environment.getExternalStorageDirectory().getAbsolutePath();
		final String filePath = String.format(
				"/%s/%s/%d.png", sdcardDir, IMG_FOLDER, System.currentTimeMillis());
		FileOutputStream out;
		try {
			out = new FileOutputStream(filePath);
			bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);	
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		bitmap.recycle();
		
		ImageInfo newImage = new ImageInfo();
		newImage.setFileName(filePath);
		String params = cameraManager.getCamera().getParameters().flatten();
		newImage.setCameraParams(params);
		newImage.setAccelerometer(activity.getViewfinderView().getAccelerometerValues());
		newImage.setMagneticField(activity.getViewfinderView().getMagnetometerValues());
        Point[] newHPoints = new Point[2];
        newHPoints[0] = horizonPoints.get(0);
        newHPoints[1] = horizonPoints.get(horizonPoints.size()-1);
        newImage.setHorizonPoints(newHPoints);
        Location loc = activity.getViewfinderView().getLastLocation();
        newImage.setLocation(loc);        
        ImageInsertTask insertTask = new ImageInsertTask();
        ImageInfo[] image = {newImage};
        insertTask.execute(image);
        
       // Intent i = new Intent(activity, ImageViewActivity.class);
        Intent i = new Intent(activity, ActiveEvaluationActivity.class);
        i.putExtra(AppConstants.BUNDLE_IMAGE_KEY, filePath);
        activity.startActivity(i);
        
        
	}
	
	 private class ImageInsertTask extends AsyncTask<ImageInfo, Void, Void> {
	     protected Void doInBackground(ImageInfo... images) {
	         ImageInfo image = images[0];
	         imageDB.putImage(image);
	         Log.d("JW", "inserted");
	         return null;
	     }
	 }

}
